﻿/// <reference path="../../../../Sustainalytics.Accounts.Admin.UI/modules/Accounts.Admin/controller/AccountDetails.ts" />
/// <reference path="../../../../Sustainalytics.Core.Admin.UI/modules/Common.Admin/filters/utilsFilters.ts" />
module Sustainalytics.EsgRatings.Admin {

    import Common = Sustainalytics.Common;
    import AdminAccounts = Sustainalytics.Accounts.Admin;
    import CommonAdmin = Sustainalytics.Common.Admin;
    
    export class ESGProfileController {

        public $scope: ng.IScope;
        public persistedProfiles: Array<ESGProfileDto> = null;
        public UI: Array<ESGProfileDto> = null;
        public DefaultProfile: ESGProfileDto = null; 
        public editedProfile:  ESGProfileDto = null; 
      
        public weightMatrices: WeightMatrix[] = null;
        
        public isLoading: boolean;
        public accountsList: AdminAccounts.AccountsDto[] = null;
        public selectedAccount: AdminAccounts.AccountsDto = null;
        public accountId: string;
        public isEdit: string = null;
        public isNewProfile: boolean;
        public defaultMatrix: WeightMatrix = null;
        public isSuggested: string = null;

        private tempMatrices: WeightMatrix[] = null;
        public referenceUniverses: IReferenceUniverse[] = [];
        public selectedReferenceUniverse: IReferenceUniverse = null;
        public DefaultReferenceUniverse:  IReferenceUniverse = null;

        private notificationFactory: Common.INotificationFactory;
        private $q: ng.IQService;
       
        constructor(
            $scope: ng.IScope,
            $rootScope,
            $q: ng.IQService,
            $location: ng.ILocationService,
            $http: ng.IHttpService,
            private AccountsService: AdminAccounts.AccountsService,
            private WeightMatricesService: IWeightMatricesService,
            private ReferenceUniversesService: IReferenceUniversesService,
            private ESGProfileBackendService: IESGProfileBackendService,
            notificationFactory: Common.INotificationFactory) {

            var ctx = this;
            $scope['esgProfile'] = this;
            ctx.$q = $q;
            ctx.$scope = $scope;
           
            ctx.notificationFactory = notificationFactory;
            ctx.DefaultProfile = new ESGProfileDto();

            ctx.getAccountSelectOptions();
            ctx.loadDefaultProfile();
            ctx.getDefaultWeightMatrix();  
            ctx.getReferenceUniverses();           
                 
        }

        public getReferenceUniverses()
        {
            var ctx = this;
            var promise = ctx.ReferenceUniversesService.getReferenceUniverses();
            promise.then(data => {
                ctx.referenceUniverses = data;
                if (data.length > 0) {
                    for (var i = 0; i < data.length; i++) {
                        if (data[i].name == 'Default') {
                            ctx.selectedReferenceUniverse = data[i];
                            ctx.DefaultReferenceUniverse  = data[i];
                        }
                    }
                }
            }).finally(() => { ctx.isLoading = false; });
        }


        public getDefaultWeightMatrix() {
            var ctx = this;

            ctx.defaultMatrix = {
                id: "00000000-0000-0000-0000-000000000000",
                name: "Default Weight Matrix",
                accountId: "00000000-0000-0000-0000-000000000000",
                isSelectedInActiveProfile: false,
                markedForDeletionOn: null,
                processedDeletionOn: null
            };
        }

        public listAccountCustomMatrices(accountId: string): ng.IPromise<WeightMatrix[]> {
            var ctx = this;
            var promise = ctx.WeightMatricesService.listWeightMatricesByAccountId(accountId, false);
         
            promise.then(data => {
                ctx.weightMatrices = data;

                if (ctx.defaultMatrix != null) {
                    if (ctx.weightMatrices != null && ctx.weightMatrices != undefined && ctx.weightMatrices.length > 0)
                        //Default Weight Matrix is placed at the first position in Weight Matrices Array
                        ctx.weightMatrices.unshift(ctx.defaultMatrix);
                    else
                        //Only Default Weight Matrix is available, if empty list
                        ctx.weightMatrices.push(ctx.defaultMatrix);
                }
            },
                (errorReason => { console.log(errorReason); })
                ).finally(() => { ctx.isLoading = false; });          
          
            return promise;
        }

        public accountIsSelected(): boolean {
            var ctx = this;
            if (this.selectedAccount != null && this.accountId != null && this.accountId !== "")
                return true;

            return false;
        }
        

        private getAccountSelectOptions() {
            var ctx = this;

            var listOptions = new CommonAdmin.HttpGetOptionsDto();

            listOptions.skip = 0;
            listOptions.take = 5000;
            listOptions.orderBy = ['name'];
            listOptions.orderAscending = true;

            //var promise = ctx.AccountsService.accountsGetList(listOptions, 'Active', '', true);
            var promise = ctx.AccountsService.accountsGetList(listOptions, 'Active', '', false);

            promise.then(data => {
                ctx.accountsList = data;
            });

            return promise;
        }

      
        public saveDefaultProfile() {
            // check if the form is valid
            var ctx = this;
            if (ctx.$scope['esgProfileForm'].$invalid) {
                ctx.notificationFactory.error('', "Invalid selection, please select at least one element in each list");
                return;
            }

            var def = this.$q.defer();
           
            ctx.ESGProfileBackendService
                .saveProfile(ctx.DefaultProfile)
                .success(data => { ctx.notificationFactory.success('Save succeeded'); def.resolve(data); })
                .error(err => { ctx.notificationFactory.error('', 'Save fails'); def.reject(); });

            return def.promise;
        }

        public loadDefaultProfile() {
            var ctx = this;
            
            var promise = ctx.ESGProfileBackendService.loadDefaultEsgProfile();
            
            promise.then(data => {
                ctx.DefaultProfile = data;
                console.log("Default Profile Name: " + ctx.DefaultProfile.name + ", Id: " + ctx.DefaultProfile.id + "; Default Weight Matrix Name:" + ctx.DefaultProfile.matrixName
                    + ", Matrix Id: " + ctx.DefaultProfile.matrixId + "; Default Reference Universe Name: " + ctx.DefaultProfile.referenceUniverseName + ", Universe Id: " + ctx.DefaultProfile.referenceUniverseId);

                if (ctx.DefaultProfile == null || ctx.DefaultProfile == undefined)
                {
                    ctx.notificationFactory.success('Default Profile is NULL');
                }
            },
                (errorReason => { console.log(errorReason); })
                ).finally(() => { ctx.isLoading = false; });
        }

        public loadEsgProfiles() {
            var ctx = this;
            var selectedAccounts = ctx.accountsList.filter(function (el) {
                return el.id === ctx.accountId;
            });

            if (selectedAccounts.length === 1) {
                ctx.selectedAccount = selectedAccounts[0];
            }

            ctx.getEsgProfilesByAccountId(ctx.accountId);
            ctx.listAccountCustomMatrices(ctx.accountId);
        }

        private getEsgProfilesByAccountId(accountId: string): ng.IPromise<ESGProfileDto[]> {
            var ctx = this;
            var promise = ctx.ESGProfileBackendService.listEsgProfileByAccountId(accountId);
          
            promise.then((profiles: ESGProfileDto[]) => {

                if (profiles.length == 0)
                    ctx.UI = new Array<ESGProfileDto>();
                else {
                    ctx.UI = profiles;
                }               
                           
                console.log(profiles);

                if (!ctx.UI)
                    ctx.UI = new Array<ESGProfileDto>();


                //Copy the elements persisted in MONGO to the destination array, that will be unaffected by Edit operations
                ctx.persistedProfiles = new Array<ESGProfileDto>();

                if (ctx.UI != null && ctx.UI != undefined && ctx.UI.length > 0) {
                    for (var i = 0; i < ctx.UI.length; i++)
                    {
                        ctx.persistedProfiles.push(ctx.UI[i]);
                    }
                }
              
                if (ctx.DefaultProfile == null)
                {
                    console.log("ESG Default Profile NULL, retrieving it now..");
                    ctx.loadDefaultProfile();
                }

                if (ctx.DefaultProfile != null) {
                    if (ctx.UI != null && ctx.UI != undefined && ctx.UI.length > 0)
                        //Default Profile is placed at the first position in profiles Array
                        ctx.UI.unshift(ctx.DefaultProfile);
                    else
                        //Only Default Profile is available, if empty list
                        ctx.UI.push(ctx.DefaultProfile);
                }
                
            },
             (errorReason => { console.log(errorReason); })
                ).finally(() => { ctx.isLoading = false; });

            return promise;
        }

        public toggleEditMode(id: string) {
            var ctx = this;

            if (id !== undefined)
                ctx.isEdit = id;

            else {              
                ctx.isEdit = undefined;
            }
        }

        public cancelEditAddEsgProfile(id: string) {
            var ctx = this;

            if (id !== undefined)
                ctx.isEdit = undefined;
            
            //Repopulate Esg Profiles list
            ctx.notificationFactory.success('Operation was cancelled.');
            ctx.getEsgProfilesByAccountId(ctx.accountId);
        }

        public getToggleState(id: string): boolean {
            var ctx = this;

            if (id === ctx.isEdit)
                return true;

            return false;
        }

        public accountIsTier1(): boolean {
            var ctx = this;

            if (ctx.selectedAccount.platformTier == AdminAccounts.AccessLevel.Tier1)
                return true;

            return false;
        }
        

        public addProfile() {
            var ctx = this;

          

            if ( ctx.UI.length <= 20) {
                ctx.editedProfile = new ESGProfileDto();

                ctx.editedProfile.id = "00000000-0000-0000-1111-000000000000";
               
                //Suggested Name
                ctx.editedProfile.name = "ESG Profile_1";

                ctx.editedProfile.companyType = CompanyTypeEnum.Combined;
                ctx.editedProfile.templateType = TemplateTypeEnum.Combined;

                ctx.editedProfile.referenceUniverseId = ctx.DefaultProfile.referenceUniverseId;
                ctx.editedProfile.referenceUniverseName = ctx.DefaultProfile.referenceUniverseName;

                //Hardcoded suggested initial value
                ctx.editedProfile.matrixId = ctx.DefaultProfile.matrixId;
                ctx.editedProfile.matrixName = ctx.DefaultProfile.matrixName;            
              
                ctx.editedProfile.active = ActiveTypeEnum.NotActive;
                ctx.isSuggested = "No";

                ctx.isNewProfile = true;            
                
                ctx.UI.unshift(ctx.editedProfile);
                ctx.toggleEditMode("00000000-0000-0000-1111-000000000000");

            }
            else {
                ctx.notificationFactory.error('', "ESG Profiles number associated to this account is 20, the maximum allowed. Please delete at least one ESG Profile.");
            }            
        }

        public saveProfile(item: any){
            var ctx = this;
            var def = this.$q.defer();
          
            var message = ctx.validateProfile(item);
            if (message === "") {

                //if (ctx.ensureNameNotDuplicate(item)){
                //    ctx.notificationFactory.error('', 'Save fails. Please ensure that the Profile Name is unique on Platform');
                //    def.reject();
                //}
                //else {              
                                                   
                    //Find Matrix Name from Id given in the UI
                    var editedMatrixId = (<ESGProfileDto>item).matrixId;
                    var editedMatrixName = ctx.findWeightMatrixName(editedMatrixId);
                    (<ESGProfileDto>item).matrixName = editedMatrixName;

                    var editedReferenceUniverseId = (<ESGProfileDto>item).referenceUniverseId;
                    var editedReferenceUniverseName = ctx.findRefUniverseName(editedReferenceUniverseId);
                    (<ESGProfileDto>item).referenceUniverseName = editedReferenceUniverseName;

                    if (ctx.isSuggested == "Yes") {
                        (<ESGProfileDto>item).active = ActiveTypeEnum.Suggested;                        
                    }
                    else if (ctx.isSuggested == "No") {
                        if ((<ESGProfileDto>item).active !== ActiveTypeEnum.Active)
                            (<ESGProfileDto>item).active = ActiveTypeEnum.NotActive;                        
                    }
                
                    //Handle Edit Profile Section 

                    if (!ctx.isNewProfile) {
                        //Set to Default 
                        (<ESGProfileDto>item).companyType = CompanyTypeEnum.Combined;
                        (<ESGProfileDto>item).templateType = TemplateTypeEnum.Combined;


                        var promise = ctx.ESGProfileBackendService
                            .saveProfile(<ESGProfileDto>item)
                            .success(data => {
                            ctx.notificationFactory.success('Save succeeded');
                            ctx.getEsgProfilesByAccountId(ctx.accountId);
                                                      
                            ctx.toggleEditMode(undefined);
                           
                            ctx.isSuggested = undefined;

                            def.resolve(data);
                        })
                            .error(err => {
                            ctx.notificationFactory.error('', 'Save fails. Please ensure that the Profile Name is unique on Platform');
                            def.reject();                                                 
                          
                        });

                        promise.then((data) => {

                        },
                            (errorReason => { console.log(errorReason); })
                            ).finally(() => { ctx.isLoading = false; });
                    }
                    else {

                        //Handle Add new profile Section 

                        (<ESGProfileDto>item).accountId = ctx.accountId;


                        var promise = ctx.ESGProfileBackendService
                            .addProfile(<ESGProfileDto>item)
                            .success(data => {
                            ctx.getEsgProfilesByAccountId(ctx.accountId);
                            ctx.isNewProfile = false;
                          
                            ctx.toggleEditMode(undefined);
                            ctx.notificationFactory.success('Add new profile succeeded');
                            def.resolve(data);
                        })
                            .error(err => {
                            ctx.notificationFactory.error('', 'Add new profile fails. Please ensure that the Profile Name is unique on Platform');
                            def.reject();                    

                        });

                        promise.then((data) => {
                        },
                            (errorReason => { console.log(errorReason); })
                            ).finally(() => { ctx.isLoading = false; });                       
                    }

               // }                
            }
            else
            {
                ctx.notificationFactory.error('', message);
            }

            return def.promise;
        }

        public  findWeightMatrixName(idM: any): string{
            
            for (var i = 0; i < this.weightMatrices.length; i++) {
                if (this.weightMatrices[i].id === idM)
                    return this.weightMatrices[i].name;
            }

            return "";
        }

        public findRefUniverseName(idM: any): string {

            for (var i = 0; i < this.referenceUniverses.length; i++) {
                if (this.referenceUniverses[i].id === idM)
                    return this.referenceUniverses[i].name;
            }

            return "";
        }
        

        public deleteProfile(item: any) {
            var ctx = this;
            var def = this.$q.defer();

            var itemId = item.id;
            if (itemId === ctx.DefaultProfile.id) {
                ctx.notificationFactory.error("", "You cannot mark for removal the default Esg Profile!");
                return;
            }

            if (confirm("Ar you sure you want to delete this ESG Profile?"))
                {
                var promise = ctx.ESGProfileBackendService
                    .deleteProfile(itemId)
                    .success(data => {
                    //Ensure removal of Esg Profile from the Grid Items
                    ctx.removeEsgProfileFromUIGrid(itemId);
                    ctx.notificationFactory.success('Delete operation succeeded');
                    def.resolve(data);
                })
                    .error(err => {
                    ctx.notificationFactory.error('', 'Delete operation fails. Please try again.');
                    def.reject();
                });

                promise.then((data) => {

                },
                    (errorReason => { console.log(errorReason); })
                    ).finally(() => { ctx.isLoading = false; });
            }
        }

        private removeEsgProfileFromUIGrid(itemId: string){
            var ctx = this;

            for (var i = 0; i <  ctx.UI.length; i++) {
                if (ctx.UI[i].id === itemId)
                    
                    //Only remove 1 EsgProfile --> the one that matches the EsgProfile Id; This ensures that the EsgProfile UI Grid is kept in sync
                    ctx.UI.splice(i, 1);
            }
        } 

        private validateProfile(item: any) {
            var ctx = this;
            var message = "";

          
            if (item.name == undefined || item.matrixId == undefined || item.matrixName == undefined || item.referenceUniverseId == undefined || item.referenceUniverseName == undefined) {
                console.log("Some fields got undefined.");
                console.log("Profile Name: " + item.name + ", Matrix Id: " + item.matrixId + "; Matrix Name:" + item.matrixName
                    + ", Reference Universe Id: " + item.referenceUniverseId + "; Reference Universe Name: " + item.referenceUniverseName);

                message += "Please check the following field(s): ";

                if (item.name == undefined)
                    message += "<br/> Esg Profile name";
                if (item.matrixId == undefined || item.matrixName == undefined)
                    message += "<br/> Matrix name";
                if (item.referenceUniverseId == undefined || item.referenceUniverseName == undefined)
                    message += "<br/> Universe name";
            }
            else {
                var newText = item.name;

                if (newText.length > 50) {
                    message += "The Esg Profile name should have maximum 50 characters.";
                }
            }
           
            return message;
        }

        private ensureNameNotDuplicate(item: any) {
            var ctx = this;
            var isDuplicate: boolean = false;
            
            //Compare item name with the most recent version of profiles persisted in MONGO - not with ctx.UI, since it is already affected by profiles Edit operations
            if (ctx.persistedProfiles != undefined && ctx.persistedProfiles != null && ctx.persistedProfiles.length > 0) {
                for (var i = 0; i < ctx.persistedProfiles.length; i++) {
                    if (ctx.persistedProfiles[i].name === item.name)
                       return true;
                }
            }

            return isDuplicate;
        }

        public  convertTemplateType(itemDto: ESGProfileDto): string {
            if (itemDto.templateType === TemplateTypeEnum.Combined) {
                return "Combined";
            }

            if (itemDto.templateType === TemplateTypeEnum.Type_A) {
                return "Type A";
            }

            if (itemDto.templateType === TemplateTypeEnum.Type_B) {
                return "Type B";
            }
        }

        public imposeTemplateType(itemDto: ESGProfileDto): string {           
            return "Combined";          
        }

        public imposeCompanyType(itemDto: ESGProfileDto): string {
            return "Combined";
        }

        public convertCompanyType(itemDto: ESGProfileDto): string {
            if (itemDto.companyType === CompanyTypeEnum.Combined) {
                return "Combined";
            }

            if (itemDto.companyType === CompanyTypeEnum.Private) {
                return "Private";
            }

            if (itemDto.companyType === CompanyTypeEnum.Public) {
                return "Public";
            }
        }

        public convertActiveStatusType(itemDto: ESGProfileDto ) : string {
            if (itemDto.active === ActiveTypeEnum.Active) {
                return "Yes";
            }

            if (itemDto.active == null || itemDto.active === ActiveTypeEnum.NotActive || itemDto.active === ActiveTypeEnum.Suggested) {
                return "No";
            }
        }

        public convertSuggestedStatusType(itemDto: ESGProfileDto): string {
            if (itemDto.active === ActiveTypeEnum.Suggested) {
                return "Yes";
            }

            if (itemDto.active == null || itemDto.active === ActiveTypeEnum.NotActive || itemDto.active === ActiveTypeEnum.Active) {
                return "No";
            }
        }

        public convertActiveStatus(activeSt: ActiveTypeEnum): string {
            if (activeSt === ActiveTypeEnum.Active) {
                return "Yes";
            }

            if (activeSt == null || activeSt === ActiveTypeEnum.NotActive || activeSt === ActiveTypeEnum.Suggested) {
                return "No";
            }
        }
    }

    // register controller with EsgRatings Angular module
    var mod = angular.module(Sustainalytics.EsgRatings.Admin.esgRatingsAdminModuleName);

    mod.controller('ESGProfileController',
        ['$scope', '$rootScope', '$q', '$location', '$http', 'AccountsService', 'WeightMatricesService', 'ReferenceUniversesService', 'ESGProfileBackendService',  'notificationFactory', Sustainalytics.EsgRatings.Admin.ESGProfileController]);
} 